package com.jetpackframework.rxmvvm;

import com.jetpackframework.rxjetpack.DisposableHelper;
import com.jetpackframework.rxjetpack.Dispose;
import com.jetpackframework.rxjetpack.DisposeImpl;
import com.jetpackframework.rxjetpack.Observable;
import com.jetpackframework.rxjetpack.Observer;

public class ObservableName<T> extends Observable<ObservableName.ObservableEntity<T>> {

    private ObservableEntity<T> observableEntity;

    public ObservableName(String name, Observable<T> observable){
        this.observableEntity = new ObservableEntity<T>(name,observable);
    }

    @Override
    public void subscribeActual(Observer<? super ObservableEntity<T>> observer) {
        ObservableNameObserver<T> nameObserver = new ObservableNameObserver<>(observableEntity,observer);
        nameObserver.run();
    }

    public static final class ObservableEntity<T>{
        private String name;
        private Observable<T> observable;

        public ObservableEntity(String name, Observable<T> observable) {
            this.name = name;
            this.observable = observable;
        }

        public String getName() {
            return name;
        }

        public Observable<T> getObservable() {
            return observable;
        }
    }

    private static final class ObservableNameObserver<T> implements Observer<ObservableEntity<T>>,Runnable {

        private final ObservableEntity<T> observableEntity;
        private final Observer<? super ObservableEntity<T>> observer;

        public ObservableNameObserver(ObservableEntity<T> observableEntity, Observer<? super ObservableEntity<T>> observer) {
            this.observableEntity = observableEntity;
            this.observer = observer;
        }

        @Override
        public void onSubscribe(Dispose dispose) {
            observer.onSubscribe(dispose);
        }

        @Override
        public void onNext(ObservableEntity<T> observableEntity) throws Exception {
            observer.onNext(observableEntity);
        }

        @Override
        public void onError(Throwable t) {
            observer.onError(t);
        }

        @Override
        public void onComplete() {
            observer.onComplete();
        }

        @Override
        public void run() {
            Dispose dispose = new DisposeImpl();
            onSubscribe(dispose);
            try {
                if(!DisposableHelper.isDispose(dispose)){
                    onNext(observableEntity);
                }
            }catch (Exception e){
                onError(e);
            }
            onComplete();
        }
    }
}
